<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    /*
    * 外观模式：
    * 为一组复杂的子系统接口提供一个更高级的统一接口，通过这个接口使得对子系统接口的访问更容易。
    *
    * 本质：封装交互 简化调用
    *
    * 外观模式的核心思想：
    * 用户不需要关心里面是如何调用，如何使用的，我们只需要有一个能提供给我们实现功能的接口就行
    * */

    //例子1：一键完成 装弹，打蛋，换蛋 三个操作
    class A{
        a1(){} //装弹
        a2(){} //打蛋
        a3(){} //换蛋

        a_init(){ //一键操作
            this.a1() //调用装弹
            this.a2() //调用打蛋
            this.a3() //调用换蛋
        }
    }

    let a = new A()

    //没有使用外观模式就需要这么繁琐
    a.a1() //装弹
    a.a2() //打蛋
    a.a3() //换蛋

    //使用外观模式
    a.a_init() //一键操作装弹打蛋换蛋


    //例子2:浏览器兼容事件监听函数
    //有的浏览器支持el.addEventListener(),而有的浏览器只支持el.attachEvent()，此时就需要用外观模式设计一个函数来兼容
    function addMyEvent(el,type,fn){ //接收参数：元素，事件类型，回调函数
        if(浏览器支持addEventListener()){
            //就使用el.addEventListener()
        }else{ //否则就是支持attachEvent()
            //就使用attachEvent()
        }
    }
    //然后以后需要使用事件监听的时候，只需要执行该兼容函数即可
    addMyEvent(el,type,fn)

    //例子3：模拟jq源码
    var A = {
        get:function (id){
            return document.getElementById(id)
        },
        css:function (id,key,value){
            this.get(id).style[key] = value
        },
        html:function (id,content){
            this.get(id).innerHTML = content
        },
    }

    //使用外观模式 直接打点调用封装好的方法 写的少
    A.html("box","这是新添加的内容")
    A.html("box1","这是新添加的内容")
    A.html("box2","这是新添加的内容")
    A.html("box3","这是新添加的内容")
    A.html("box4","这是新添加的内容")
    A.html("box5","这是新添加的内容")

    //不使用外观模式 需要一条一条调用各种方法 很繁琐
    document.getElementById("box").innerHTML("这是新添加的内容")
    document.getElementById("box1").innerHTML("这是新添加的内容")
    document.getElementById("box2").innerHTML("这是新添加的内容")
    document.getElementById("box3").innerHTML("这是新添加的内容")
    document.getElementById("box4").innerHTML("这是新添加的内容")
    document.getElementById("box5").innerHTML("这是新添加的内容")


    //例子4：模拟电脑开机
    //不使用外观模式的电脑开机
    function Cpu(){
        this.startUp = function (){
            console.log("Cpu启动")
        }
    }
    function Memory(){
        this.startUp = function (){
            console.log("Memory启动")
        }
    }
    function Disk(){
        this.startUp = function (){
            console.log("Disk启动")
        }
    }

    //使用外观模式
    function Computer(){
        var _cpu,_memory,_disk
        _cpu = new Cpu()
        _memory = new Memory()
        _disk = new Disk()

        this.start = function (){
            _cpu.startUp() //cpu调用启动函数
            _memory.startUp() //memory调用启动函数
            _disk.startUp() //disk调用启动函数
        }
    }

    let c = new Computer() //实例化对象
    c.start() //对象直接打点调用方法就可一键操作电脑三个硬件启动



</script>
</body>
</html>